<script setup lang="ts">
  import qs from 'qs';
  import {
    GetRegion,
    updatePost,
    RegionQueryDetails,
    savePost,
    RegionQuery,
    SplitPermission,
    SplithavePermission,
    SplithavePermission1,
  } from '@/api/commandPages';
  import LeftTree from './components/leftTree.vue';
  import rightLowCode from './components/rightLowCode.vue';
  import {
    menuShowDialogTs,
    formData,
    dataList,
    rightMenuList,
    notice,
    isState,
    formSplitData,
    splitShowDialog,
  } from './components';
  import useLoading from '@/hooks/loading';
  const container = ref<HTMLElement | null>(null);
  import { cloneDeep, throttle } from 'lodash-es';
  const { loadingIcon, setLoading } = useLoading();
  const dataSelect = ref<Array<Namespace.commandType>>([]);
  const submitData = ref<Namespace.commandRegion>({});
  const submitSplitData = ref<split>({});
  const myform = ref<any>(null);
  const myformSplit = ref<any>(null);
  const title = ref<string>('新增权限点');
  const menuShowDialog = ref<boolean>(false);
  const regionCode = ref<number>();
  const TreeList = ref<Namespace.unitTree[]>();
  const rightData = ref<Namespace.commandRegion>();
  const rightShow = ref<boolean>(false);
  const selected = ref<number>();
  const UnitList = ref<{ value: number; label: string }[]>([]);
  const UnitListOriginal = ref<{ value: number; label: string }[]>([]);
  interface widthType {
    width: number;
  }
  const widthData: widthType = reactive({
    width: 300,
  });
  provide('container', container);
  onMounted(async () => {
    const { data } = await GetRegion();
    dataSelect.value = data;
    regionCode.value = dataSelect.value[0].value;
    await getTree();
    updateWidth();
  });
  const updateWidth = () => {
    let resize = document.getElementById('asideId') as HTMLElement;
    resize.onmousedown = function (e) {
      // resize.style.background = '#818181';
      let startX = e.clientX;
      // resize.left = resize.offsetLeft;
      document.onmousemove = function (e) {
        let endX = e.clientX;
        let moveLen = endX - startX;
        startX = endX;
        widthData.width += moveLen;
      };
      document.onmouseup = function () {
        // 颜色恢复
        resize.style.background = '';
        document.onmousemove = null;
        document.onmouseup = null;
      };
      return false;
    };
  };
  /** 树形组件传值过来的数据 */
  const sendGrandsonCom = async (value) => {
    rightData.value = value;
  };

  watch(
    rightData,
    (value) => {
      if (value?.id) {
        rightShow.value = true;
      } else {
        rightShow.value = false;
      }
    },
    { deep: true },
  );
  provide('sendHandleCom', sendGrandsonCom);
  const getTree = async () => {
    const { data } = await RegionQuery({ regionId: regionCode.value as number });
    TreeList.value = [data];
    handleList(TreeList.value);
    UnitList.value = UnitListOriginal.value.filter((item) => item.value != 0);
  };
  // 数据处理
  const handleList = (list: Namespace.unitTree[]) => {
    for (const node of list) {
      UnitList.value.push({ label: node.text, value: Number(node.id) });
      UnitListOriginal.value.push({ label: node.text, value: Number(node.id) });
      if (node.children && node.children.length > 0) {
        handleList(node.children);
      }
    }
  };
  const handleClose = () => {
    myform.value.reset();
    menuShowDialog.value = false;
    menuShowDialogTs.value = false;
  };
  const handleValueChange = async (val: number) => {
    regionCode.value = val as number;
    rightData.value = {};
    UnitList.value = [];
    UnitListOriginal.value = [];
    getTree();
  };
  watch(
    notice,
    (value: boolean) => {
      if (value) {
        getTree();
        notice.value = false;
      }
    },
    {
      deep: true,
    },
  );
  const handleSelectChange = (value: boolean) => {
    rightShow.value = value;
  };
  watch(
    menuShowDialogTs,
    async (value: boolean) => {
      menuShowDialog.value = value;
      if (value) {
        if (dataList.value) {
          const { data } = await RegionQueryDetails({ id: dataList.value.id as number });
          if (isState.value == 'edit') {
            formData.formFields = data;
          }

          if (isState.value == 'add') {
            formData.formFields = {
              permissionName: '',
              regionId: regionCode.value,
              parentId: dataList.value.id,
            };
            formData.formRules = [
              [
                {
                  title: '名称',
                  required: true,
                  field: 'permissionName',
                  placeholder: '请输入名称',
                  type: 'text',
                  colSize: 12,
                },
              ],
            ];
            title.value = '新增权限点';
          } else {
            formData.formRules = [
              [
                {
                  title: '父级单元',
                  required: true,
                  field: 'parentId',
                  dataKey: 'value',
                  dataName: 'label',
                  default: '',
                  placeholder: '请选择父级单元',
                  type: 'select',
                  colSize: 12,
                  data: [],
                },
              ],
              [
                {
                  title: '名称',
                  required: true,
                  field: 'permissionName',
                  placeholder: '请输入名称',
                  type: 'text',
                  colSize: 12,
                },
              ],
            ];
            title.value = '修改权限点';
          }
          const dataMap = UnitListOriginal.value.filter(
            (item) => item.value != formData.formFields.id,
          );

          formData.formRules &&
            formData.formRules.map((it) => {
              it.filter(async (item) => {
                if (item.field == 'parentId') {
                  item.data = dataMap;
                }
              });
            });
        }
      }
    },
    {
      deep: true,
    },
  );

  const hanldFromData = async (value: Object) => {
    submitData.value = value;
  };
  const getForm = throttle(async () => {
    myform.value.validate();
    await setTimeout(async () => {
      setLoading(true);
      if (myform.value.success) {
        try {
          if (submitData.value.id) {
            const { code } = await updatePost(qs.stringify(submitData.value));
            if (code === 0) {
              menuShowDialog.value = false;
              menuShowDialogTs.value = false;
              handleValueChange(regionCode.value as number);
            }
          } else {
            const { code } = await savePost(qs.stringify(submitData.value));
            if (code === 0) {
              menuShowDialog.value = false;
              menuShowDialogTs.value = false;
              handleValueChange(regionCode.value as number);
            }
          }
          selected.value = submitData.value.parentId;
        } catch (error) {
          setLoadingFalse();
        } finally {
          setLoadingFalse();
        }
      }
      setLoadingFalse();
    });
  });
  const setLoadingFalse = () => {
    setTimeout(() => {
      setLoading(false);
    }, 500);
  };
  const reset = async () => {
    await setTimeout(() => {
      myform.value.reset();
      formData.formFields = {
        parentId: '',
        permissionName: '',
      };
    });
  };
  const handleSplitClose = () => {
    splitShowDialog.value = false;
  };
  const hanldFromSplitData = async (value: Object) => {
    submitSplitData.value = value;
  };
  const sendGrandsonComIds = (value: number[]) => {
    if (rightData.value?.parentId == 0) {
      formSplitData.formFields = {
        parentName: '',
        splitName: '',
        origId: rightData.value?.id,
        perIds: value ? value.toString() : '',
      };
      formSplitData.formRules = [
        [
          {
            title: '父级名称',
            required: true,
            field: 'parentName',
            placeholder: '请输入父级名称',
            type: 'text',
            colSize: 12,
          },
        ],
        [
          {
            title: '拆分名称',
            required: true,
            field: 'splitName',
            placeholder: '请输入拆分名称',
            type: 'text',
            colSize: 12,
          },
        ],
      ];
    } else {
      formSplitData.formFields = {
        parentId: rightData.value?.parentId,
        splitName: '',
        origId: rightData.value?.id,
        perIds: value ? value.toString() : '',
        radio: '0',
      };
      formSplitData.formRules = [
        [
          {
            title: '拆分名称',
            required: true,
            field: 'splitName',
            placeholder: '请输入拆分名称',
            type: 'text',
            colSize: 12,
          },
        ],
        [
          {
            dataKey: 'key',
            dataName: 'value',
            title: '拆分选择',
            required: true,
            placeholder: '请选择',
            field: 'radio',
            data: [
              { key: '0', value: '拆分同级' },
              { key: '1', value: '拆分子级' },
            ],
            type: 'radio',
          },
        ],
      ];
    }
  };
  provide('sendHandleComIds', sendGrandsonComIds);
  const getSplitForm = throttle(async () => {
    myformSplit.value.validate();
    await setTimeout(async () => {
      setLoading(true);
      if (myformSplit.value.success) {
        try {
          if (submitSplitData.value.parentName) {
            rightShow.value = false;
            try {
              const { code } = await SplitPermission(submitSplitData.value);
              if (code === 0) {
                selected.value =
                  submitSplitData.value.radio == '0'
                    ? (submitSplitData.value.parentId as unknown as number)
                    : (submitSplitData.value.origId as unknown as number);
                resetSplit();
                await getTree();
                splitShowDialog.value = false;
              }
            } catch {
              rightShow.value = true;
            }
            rightShow.value = true;
          } else if (submitSplitData.value.radio == '0') {
            rightShow.value = false;
            try {
              const data = {
                ...cloneDeep(submitSplitData.value),
              };
              delete data.radio;
              const { code } = await SplithavePermission(data);
              if (code === 0) {
                selected.value = submitSplitData.value.parentId as unknown as number;
                resetSplit();
                await getTree();
                splitShowDialog.value = false;
              }
            } catch {
              rightShow.value = true;
            }
            rightShow.value = true;
          } else if (submitSplitData.value.radio == '1') {
            rightShow.value = false;
            try {
              const data = {
                ...cloneDeep(submitSplitData.value),
              };
              delete data.radio;
              const { code } = await SplithavePermission1(data);
              if (code === 0) {
                selected.value = submitSplitData.value.origId as unknown as number;
                resetSplit();
                await getTree();
                splitShowDialog.value = false;
              }
            } catch {
              rightShow.value = true;
            }
            rightShow.value = true;
          }
        } catch (error) {
          setLoadingFalse();
        } finally {
          setLoadingFalse();
        }
      }
      setLoadingFalse();
    });
  });
  const resetSplit = async () => {
    await setTimeout(() => {
      myformSplit.value.reset();
      if (rightData.value?.parentId == 0) {
        formSplitData.formFields = {
          ...formSplitData.formFields,
          parentName: '',
          splitName: '',
        };
      } else {
        formSplitData.formFields = {
          ...formSplitData.formFields,
          parentId: rightData.value?.parentId,
          origId: rightData.value?.id,
        };
      }
    });
  };
</script>

<template>
  <div class="commonpand-layout">
    <ElContainer style="height: 100%">
      <div
        id="asideId"
        :style="{ width: widthData.width + 'px' }"
        ref="container"
        class="commonpand-layout-left"
      >
        <ElAside>
          <!-- 由于之前是不同的展示方式，所以这个组件新开一个 -->
          <LeftTree
            :data="dataSelect"
            @update:namevalue="handleValueChange"
            @updateRight:show="handleSelectChange"
            :rightMenuList="rightMenuList"
            :formData="formData"
            :treeList="TreeList"
            :regionCode="regionCode"
            :rightShow="rightShow"
            :UnitList="UnitList"
            :selected="selected"
          />
        </ElAside>
      </div>
      <ElMain class="commonpand-layout-right">
        <rightLowCode :data="rightData" :regionCode="regionCode" v-if="rightShow" />
      </ElMain>
    </ElContainer>
    <ElDialog
      :model-value="menuShowDialog"
      :title="title"
      :before-close="handleClose"
      :destroy-on-close="true"
    >
      <ElementForm
        ref="myform"
        :loadKey="formData.loadKey"
        :formFields="formData.formFields"
        :formRules="formData.formRules"
        :labelWidth="110"
        @update:value="hanldFromData"
      >
        <div style="text-align: center">
          <ElButton type="primary" :loading="loadingIcon" @click="getForm">提交</ElButton>
          <ElButton @click="reset">重置表单</ElButton>
        </div>
      </ElementForm>
    </ElDialog>
    <ElDialog
      :model-value="splitShowDialog"
      title="拆分权限"
      :before-close="handleSplitClose"
      :destroy-on-close="true"
    >
      <ElementForm
        ref="myformSplit"
        :loadKey="formSplitData.loadKey"
        :formFields="formSplitData.formFields"
        :formRules="formSplitData.formRules"
        :labelWidth="110"
        @update:value="hanldFromSplitData"
      >
        <div style="text-align: center">
          <ElButton type="primary" :loading="loadingIcon" @click="getSplitForm">提交</ElButton>
          <ElButton @click="resetSplit">重置表单</ElButton>
        </div>
      </ElementForm>
    </ElDialog>
  </div>
</template>

<style lang="scss" scoped>
  .commonpand-layout {
    height: $height;
    &-right {
      padding: 0;
    }
    &-left {
      height: $height;
      width: 300px;
      background-color: var(--el-color-white);
      :deep(.el-aside) {
        height: $height;
        width: $width;
        overflow: visible;
      }
    }
  }
</style>
